home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1999
/
MacHack 1999.toast
/
The Hacks
/
DesktopDoubler
/
NubApp
/
Main.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-25
|
6KB
|
311 lines
#define DISABLE_LOCAL_CALLTRACE 1 // Set to 1 to disable Call Traces for this file.
#define DISABLE_LOCAL_DEBUG 0 // Set to 1 to disable all debugging for this file.
#include "DebugUtils.h"
#include <Appearance.h>
#include <Dialogs.h>
#include <Fonts.h>
#include <Gestalt.h>
#include <LowMem.h>
#include <Resources.h>
#include <stdio.h>
#include <TextEdit.h>
#include <Traps.h>
#include "Event.h"
#include "ContextUtils.h"
#include "Main.h"
#include "Menu.h"
#include "MetroNubUtils.h"
#include "Notice.h"
#include "Nub.h"
#include "Window.h"
typedef pascal void (*ExitToShellProcPtr)(void);
enum
{
uppExitToShellProcInfo = kPascalStackBased
};
#if GENERATINGCFM
typedef UniversalProcPtr ExitToShellUPP;
#define NewExitToShellProc(userRoutine) \
(ExitToShellUPP)NewRoutineDescriptor((ProcPtr)(userRoutine),uppExitToShellProcInfo,GetCurrentArchitecture())
#define CallExitToShellProc(userRoutine) \
CallUniversalProc((UniversalProcPtr)(userRoutine),uppExitToShellProcInfo)
#else
typedef ExitToShellProcPtr ExitToShellUPP;
#define NewExitToShellProc(userRoutine) ((ExitToShellUPP)(userRoutine))
#define CallExitToShellProc(userRoutine) (*(((ExitToShellUPP)userRoutine)))()
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern OSStatus NubMain(Handle code);
static void Initialize(void);
static void CleanUp(void);
static void MainEventLoop(void);
static pascal void ExitToShellPatch(void);
#ifdef __cplusplus
}
#endif
#if GENERATINGCFM
static RoutineDescriptor gExitToShellPatchRD = BUILD_ROUTINE_DESCRIPTOR(uppExitToShellProcInfo,ExitToShellPatch);
static ExitToShellUPP gExitToShellPatchUPP = (ExitToShellUPP)&gExitToShellPatchRD;
static ExitToShellUPP gExitToShellUPP;
#elif __A5__
static ExitToShellUPP gExitToShellPatchUPP = ExitToShellPatch;
static ExitToShellUPP gExitToShellUPP;
#endif
Boolean gExitToShellHasBeenCalled = false;
Boolean gWeAreBeingDebugged = false;
EventManager *gEventManager = NULL;
MenuManager *gMenuManager = NULL;
WindowManager *gWindowManager = NULL;
Boolean gExitFlag = false;
FileMenu *gFileMenu = NULL;
void main(void)
{
NubInfo *info = NULL;
Handle code = NULL;
OSStatus err;
Initialize();
// Get NubInfo from Gestalt.
err = Gestalt(kNubSelector,(long*)&info);
if (err != noErr)
info = NULL;
// Check for prior existence of the Nub.
if ((err != noErr) || (info == NULL))
{
PostNotice(kAlertStopAlert,"\pNub is not installed!","\pThis app requires that " \
"\pthe Nub be installed at startup to load the required system patches.");
ExitToShell();
}
// Check if the Nub is currently loaded.
if (info->signature == kNubSignature)
{
if (info->unloadProc == NULL)
{
PostNotice(kAlertStopAlert,"\pNub couldn't be unloaded!","\pNub " \
"\pappears to be loaded, but there isn't a registered unload procedure.");
ExitToShell();
}
// Unload Nub.
{
THzContext zone(SystemZone());
err = CallNubUnloadProc(info->unloadProc,&code);
if (err != noErr)
{
Str255 msg;
msg[0] = sprintf((char*)&msg[1],"The Nub unload procedure failed: %ld",err);
PostNotice(kAlertStopAlert,"\pNub couldn't be unloaded!",msg);
ExitToShell();
}
}
if (code != NULL)
DisposeHandle(code);
}
// Load app-based Nub.
{
THzContext zone(SystemZone());
err = NubMain(NULL);
if (err != noErr)
{
Str255 msg;
msg[0] = sprintf((char*)&msg[1],"The Nub load procedure failed: %ld",err);
PostNotice(kAlertStopAlert,"\pNub couldn't be loaded!",msg);
ExitToShell();
}
}
// Patch ExitToShell so we can guarantee our clean up.
gExitToShellUPP = (ExitToShellUPP)NGetTrapAddress(_ExitToShell,ToolTrap);
NSetTrapAddress((UniversalProcPtr)gExitToShellPatchUPP,_ExitToShell,ToolTrap);
MainEventLoop();
}
void Initialize(void)
{
SInt32 result;
OSStatus err;
// Expand our heap to is maximum, this
// will help keep fragmentation low, etc.
MaxApplZone();
// Init toolbox.
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
InitCursor();
TEInit();
FlushEvents(everyEvent,0);
InitDialogs(NULL);
// Check for Appearance Manager.
err = Gestalt('appr',&result);
if ((err == noErr) && (result & 1))
RegisterAppearanceClient();
// Check for high-level debugger.
if (AmIBeingMWDebugged())
gWeAreBeingDebugged = true;
InitAppleEvents();
gEventManager = new BaseEventManager;
gMenuManager = new BaseMenuManager;
gWindowManager = new BaseWindowManager;
new AppleMenu;
gFileMenu = new FileMenu;
new EditMenu;
DrawMenuBar();
}
void CleanUp(void)
{
NubInfo *info = NULL;
Handle code = NULL;
OSStatus err;
// Get NubInfo from Gestalt.
err = Gestalt(kNubSelector,(long*)&info);
if (err != noErr)
info = NULL;
// Check for current existence of the Nub.
if ((err != noErr) || (info == NULL))
{
PostNotice(kAlertStopAlert,"\pNub is not installed!","\pNub was installed when I launched "\
"\pso I don't know why your seeing this now, there is a very good chance that your going crash!");
return;
}
// Check if Nub is currently loaded.
if (info->signature == kNubSignature)
{
if (info->unloadProc == NULL)
{
PostNotice(kAlertStopAlert,"\pNub couldn't be unloaded!","\pNub didn't register an unload " \
"\pprocedure, however since we loaded successfully there is a very good chance that your going crash!");
return;
}
// Unload Nub.
{
THzContext zone(SystemZone());
err = CallNubUnloadProc(info->unloadProc,&code);
if (err != noErr)
{
Str255 msg;
msg[0] = sprintf((char*)&msg[1],"The Nub unload procedure failed: %ld, there is a " \
"very good chance that your going crash!",err);
PostNotice(kAlertStopAlert,"\pNub couldn't be unloaded!",msg);
return;
}
}
if (code != NULL)
DisposeHandle(code);
}
}
void SubEventLoop(short eventMask,UInt32 sleepTime)
{
EventRecord event;
Boolean result;
result = WaitNextEvent(eventMask,&event,sleepTime,NULL);
gEventManager->DoDispatch(&event);
}
void MainEventLoop(void)
{
gExitFlag = false;
while(!gExitFlag)
SubEventLoop(everyEvent,60L);
}
pascal void ExitToShellPatch(void)
{
#if __A5__
SetCurrentA5();
#endif
if (!gExitToShellHasBeenCalled)
{
gExitToShellHasBeenCalled = true;
CleanUp();
}
CallExitToShellProc(gExitToShellUPP);
}
void InitiateAppQuit(void)
{
gExitFlag = true;
}